package com.lh0811.forge.dependency.security.client.service.impl;

import com.lh0811.forge.dependency.basic_web.exception.CommonException;
import com.lh0811.forge.dependency.basic_web.response.ServerResponse;
import com.lh0811.forge.dependency.security.client.component.provide.ProvideResToSecurityClient;
import com.lh0811.forge.dependency.security.client.service.SecurityClient;
import com.lh0811.forge.dependency.security.core.model.entity.SecurityAuthority;
import com.lh0811.forge.dependency.security.core.model.entity.SecurityRes;
import com.lh0811.forge.dependency.security.core.model.properties.SecurityBootProperties;
import com.lh0811.forge.dependency.security.core.token.TokenManager;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 客户端组件
 *
 * @author lh0811
 * @date 2021/5/24
 */
@Slf4j
public class DefaultSecurityClientImpl implements SecurityClient {

    @Resource
    private ProvideResToSecurityClient provideResToSecurityClient;

    @Resource
    private SecurityBootProperties properties;

    @Resource
    private TokenManager tokenManager;

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public SecurityAuthority tokenToAuthority() throws Exception {
        String token = provideResToSecurityClient.getTokenFromApplicationContext();
        if (StringUtils.isBlank(token)) {
            throw CommonException.create(ServerResponse.createByError(Integer.valueOf(properties.getNoAuthorizedCode()), "未上传用户token", ""));
        }
        // 获取到token对应存储的用户权限信息
        SecurityAuthority securityAuthority = tokenManager.getSecurityAuthorityByToken(token);
        if (ObjectUtils.isNotEmpty(securityAuthority)) {
            // 每次认证后给token续期
            tokenManager.delayExpired(token);
            return securityAuthority;
        }
        throw CommonException.create(ServerResponse.createByError("token解析失败。"));
    }

    @Override
    public SecurityAuthority hasUrl(String url) throws Exception {
        // 获取到当前权限信息
        SecurityAuthority securityAuthority = tokenToAuthority();
        // 获取到所有的url权限
        if (CollectionUtils.isEmpty(securityAuthority.getSecurityUser().getResList())) {
            throw CommonException.create(ServerResponse.createByError(properties.getUnAuthorizedCode(), "该用户没有权限访问当前资源"));
        }
        // 获取到所有的url
        List<String> urlMatcherList = securityAuthority.getSecurityUser().getResList().stream().map(ele -> ele.getUrl()).collect(Collectors.toList());
        for (String urlMatcher : urlMatcherList) {
            if (antPathMatcher.match(urlMatcher, url)) {
                return securityAuthority;
            }
        }
        throw CommonException.create(ServerResponse.createByError(Integer.valueOf(properties.getUnAuthorizedCode()), "该用户没有权限访问当前资源", ""));
    }

    @Override
    public SecurityAuthority hasACLCode(String aclCode) throws Exception {
        // 获取到当前权限信息
        SecurityAuthority securityAuthority = tokenToAuthority();
        // 获取到所有的权限
        if (CollectionUtils.isEmpty(securityAuthority.getSecurityUser().getResList())) {
            throw CommonException.create(ServerResponse.createByError(properties.getUnAuthorizedCode(), "该用户没有权限访问当前资源"));
        }
        // 获取到所有的code
        List<String> codeList = securityAuthority.getSecurityUser().getResList().stream().map(ele -> ele.getCode()).collect(Collectors.toList());

        for (String code : codeList) {
            if (codeList.contains(SecurityRes.ALL) || code.equalsIgnoreCase(aclCode)) {
                return securityAuthority;
            }
        }
        throw CommonException.create(ServerResponse.createByError(properties.getUnAuthorizedCode(), "该用户没有权限访问当前资源"));
    }


}
